import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_common/ui/widget/click.dart';
import 'package:flutter_common/util/context_extension.dart';
import 'package:flutter_common/util/logger.dart';
import 'package:flutter_common/util/string_utils.dart';
import 'package:flutter_common/util/toast_util.dart';
import 'package:flutter_screen_recording_example/play_view.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:video_player/video_player.dart';

///视频播放：可以文件MP4，mp3则可能存在时长获取不正确，可以证据对象，可以在线播放url
class VideoPlayPage extends StatefulWidget {
  final File? file;
  final Future<String> Function()? onUrlCallback;
  final bool showTitleBar;

  const VideoPlayPage({super.key, this.file, this.onUrlCallback,this.showTitleBar = true});

  @override
  State<StatefulWidget> createState() => _VideoPlayPageState();
}

class _VideoPlayPageState extends State<VideoPlayPage> with AutomaticKeepAliveClientMixin{
  late final _model = VideoPlayViewModel(
    file: widget.file,
    onUrlCallback: widget.onUrlCallback,
  );

  @override
  void dispose() {
    _model.dispose();
    super.dispose();
  }

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Material(
      color: Colors.black,
      child: Stack(
        children: [
          if (widget.showTitleBar)
            WillPopScope(
              child: Container(),
              onWillPop: () {
                _model.onBackPress(context);
                return Future.value(false);
              },
            ),
          Center(
            child: SafeArea(
              child: Padding(
                padding: const EdgeInsets.only(bottom: 0),
                child: ValueListenableBuilder(
                  valueListenable: _model.isPlaying,
                  builder: (context, value, child) {
                    if (_model.controller == null) return const SizedBox();
                    return AspectRatio(
                      aspectRatio: _model.controller!.value.aspectRatio,
                      child: VideoPlayer(_model.controller!),
                    );
                  },
                ),
              ),
            ),
          ),
          Center(child: _errorWidget()),
          _tips(),
          _overlay(),
        ],
      ),
    );
  }

  Widget _tips(){
    return Center(
      child: ValueListenableBuilder<String?>(
        valueListenable: _model.errorTips,
        builder: (context, v, c) {
          return FxClick(
            onTap: () => _model.onPlayPress(context),
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
              child: Text(v??'',style: const TextStyle(color: Colors.white),),
            ),
          );
        },
      ),
    );
  }

  Widget _overlay() {
    return Column(
      children: [
        FutureBuilder(
          builder: (context, s) => Container(),
          future: _model.checkPlaySource(context),
        ),
        const SafeArea(child: SizedBox(height: 1)),
        // if (widget.showTitleBar)
        //   ValueListenableBuilder<String>(
        //     valueListenable: _model.title,
        //     builder: (con, value, child) {
        //       return PlayTitle(
        //         title: value,
        //         showRight: _model.showRight,
        //         onRightTap: () => _model.onEditNamePress(context),
        //         onCloseTap: () => _model.onBackPress(context),
        //       );
        //     },
        //   ),
        const SizedBox(height: 15),
        // const VolumeView(),
        const Expanded(child: SizedBox()),
        const SizedBox(height: 15),
        // Padding(
        //   padding: const EdgeInsets.fromLTRB(28, 0, 28, 0),
        //   child: _playSlider(),
        // ),
        const SizedBox(height: 8),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 32),
          child: _time(),
        ),
        const SizedBox(height: 20),
        ValueListenableBuilder<bool>(
          valueListenable: _model.isPlaying,
          builder: (context, value, child) {
            return PlayButton(
              playing: value,
              onTap: () => _model.onPlayPress(context),
            );
          },
        ),
        const SizedBox(height: 7),
        _textWidget(_model.playingTips, color: Colors.white.withOpacity(0.7)),
        const SafeArea(child: SizedBox()),
      ],
    );
  }

  // Widget _playSlider() {
  //   return SliderTheme(
  //     data: getSliderData(context),
  //     child: ValueListenableBuilder<double>(
  //       valueListenable: _model.curTime,
  //       builder: (con, value, child) {
  //         var dur = _model.duration.value;
  //         return Slider(
  //           value: value <= dur ? value : dur,
  //           max: dur,
  //           min: 0.0,
  //           //user drag start、end、drag
  //           onChangeStart: _model.onPlayChanged,
  //           onChangeEnd: _model.onPlayChanged,
  //           onChanged: (v) {
  //             _model.curTime.value = v;
  //           },
  //         );
  //       },
  //     ),
  //   );
  // }

  Widget _time() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        _textWidget(_model.curTimeStr),
        _textWidget(_model.durationStr),
      ],
    );
  }

  ///文本
  Widget _textWidget(ValueNotifier<String> v, {Color? color}) {
    return ValueListenableBuilder<String>(
      valueListenable: v,
      builder: (context, value, child) {
        return Padding(
          padding: const EdgeInsets.symmetric(vertical: 1),
          child: Text(
            value,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: color ?? Colors.white.withOpacity(0.5),
            ),
          ),
        );
      },
    );
  }

  ///播放异常，有可能出现 初始化失败--资源未释放导致，需要通过kill app处理
  Widget _errorWidget(){
    return ValueListenableBuilder<bool>(
      valueListenable: _model.isPlaying,
      builder: (context, value, child) {
        if (_model.controller == null) return const SizedBox();
        return ValueListenableBuilder<VideoPlayerValue>(
          valueListenable: _model.controller!,
          builder: (context, value, child) {
            if(!value.hasError) return const SizedBox();
            return Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text('smart_refresh_empty.png'),
                const SizedBox(height: 12),
                Text(
                  "加载失败，请尝试后台关闭app重新进入打开",
                  style: TextStyle(color: Colors.white),
                )
              ],
            );
          },
        );
      },
    );
  }
}

///视频播放 控制
class VideoPlayViewModel {
  //文件来源
  final File? file;

  //播放状态
  final ValueNotifier<bool> isPlaying = ValueNotifier<bool>(false);
  final playingTips = ValueNotifier<String>("开始播放");

  //播放时长、当前时间点
  final duration = ValueNotifier<double>(0.0);
  final curTime = ValueNotifier<double>(0.0);
  final durationStr = ValueNotifier<String>("00:00");
  final curTimeStr = ValueNotifier<String>("00:00");

  //标题
  final title = ValueNotifier<String>("");
  final errorTips = ValueNotifier<String?>(null);
  bool change = false;

  //播放控制
  VideoPlayerController? controller;

  //当前播放路径
  String? _playSource;
  Future<String> Function()? _getPlayUrl;

  VideoPlayViewModel({this.file, Future<String> Function()? onUrlCallback}) {
    setPlayUrl = onUrlCallback;
  }

  ///设置 获取播放url的方法
  set setPlayUrl(Future<String> Function()? func) => _getPlayUrl = func;

  ///确认播放资源
  Future checkPlaySource(BuildContext context) async {
    if (_playSource == null) {
      // var c = await checkPermissionAndRequest(context, [Permission.storage]);
      // if (ToastUtil.toast(!c, "存储权限未开启，无法读取文件")) return;
    }
    await _getPlaySource();
  }

  ///释放播放资源
  dispose() {
    controller?.removeListener(_listener);
    controller?.dispose();
    controller = null;
  }

  String _getFormatDuration(int inSeconds) {
    return StringUtils.getFormatDuration(inSeconds).replaceFirst("00:", "");
  }

  ///根据参数获取 访问来源：优先  url、setPlayUrl、bean.previewUrl、file、localPath、filePath
  Future<VideoPlayerController?> _source(File? file)async{
    if(file != null){
      if(!_setErrorTips(!file.existsSync(),"文件不存在，无法预览")){
        return VideoPlayerController.file(file);
      }
    }
    return null;
  }
  ///获取播放 来源
  _getPlaySource() async {
    errorTips.value = null;

    //设置source
    controller = await _source(file);
    _playSource = controller?.dataSource;
    //测试test
    // if (playSource == null) {
    //   bool c = await StorageUtils.hasStoragePermission();
    //   if (ToastUtil.toast(!c, "文件目录不存在，无法读取文件")) return;
    //   var f = File("${StorageUtils.videoDir}xjlx.mp4");
    //   if(ToastUtil.toast(!await f.exists(), "文件不存在")) return;
    //   playSource ??= f.path;
    //   controller = VideoPlayerController.file(File(playSource!));
    // }
    if (ToastUtil.toast(_playSource.isNullOrBlank || controller == null, "文件不存在")) {
      errorTips.value = errorTips.value ?? "文件或链接不存在，无法预览";
      return;
    }
    errorTips.value = "";
    controller!.addListener(_listener);
    await controller!.initialize();
  }

  _setErrorTips(bool error,String tips){
    if(error){
      //不为空才赋值
      errorTips.value = errorTips.value ?? tips;
    }
    return error;
  }

  ///播放控制回调监听
  _listener() {
    var v = controller?.value;
    if (v == null || v.isInitialized != true) {
      logger.debug("video play v.isInitialized false ${v?.isInitialized} source $_playSource");
      errorTips.value = errorTips.value ?? "初始化失败，无法播放";
      return;
    }
    errorTips.value = v.isPlaying || errorTips.value == null ? null : "点击按钮开始播放";
    duration.value = v.duration.inMilliseconds.toDouble();
    durationStr.value = _getFormatDuration(v.duration.inSeconds);
    curTime.value = v.position.inMilliseconds.toDouble();
    curTimeStr.value = _getFormatDuration(v.position.inSeconds);
    if(!v.isPlaying && curTime.value > 0 &&duration.value == curTime.value){
      //防止播放结束后，重新播放时 多次进入该条件
      controller?.seekTo(const Duration());
      curTime.value = 0;
      curTimeStr.value = "00:00";
      _switchPlayUI(false);
    }
  }

  ///播放、暂停
  Future onPlayPress(BuildContext context) async {
    var v = controller?.value;
    if (v?.isPlaying == true) {
      await switchPlay(false);
    } else if (v?.isPlaying == false) {
      await switchPlay(true);
    } else {
      if (_playSource == null && context.mounted) {
        await checkPlaySource(context);
      }
      if (controller == null ||
          ToastUtil.toast(
              controller?.value.isInitialized != true, "初始化失败，请重试")) {
        return;
      }
      await switchPlay(true);
    }
  }

  ///切换播放、暂停
  switchPlay([bool playing = false])async{
    if(controller == null){
      return;
    }
    errorTips.value = null;
    if(playing){
      await controller!.play();
      _switchPlayUI(true);
    }else{
      await controller!.pause();
      _switchPlayUI(false);
    }
  }

  ///切换播放ui
  _switchPlayUI([bool playing = false]) {
    isPlaying.value = playing;
    if (playing) {
      playingTips.value = "暂停播放";
      return;
    }
    playingTips.value = "开始播放";
  }

  ///进度条 变化
  onPlayChanged(double v) {
    controller?.seekTo(Duration(milliseconds: v.toInt()));
  }

  onBackPress(BuildContext context) {
    context.pop(change);
  }
}
